package org.example.springboot.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.example.springboot.common.config.MqttClientManager;
import org.example.springboot.common.config.RefreshConfig;
import org.example.springboot.common.page.PageResult;
import org.example.springboot.common.service.impl.BaseServiceImpl;
import org.example.springboot.common.utils.Result;
import org.example.springboot.component.SseEmitterServer;
import org.example.springboot.convert.FmcControlConvert;
import org.example.springboot.dao.FmcControlDao;
import org.example.springboot.entity.*;
import org.example.springboot.query.FmcControlQuery;
import org.example.springboot.service.*;
import org.example.springboot.vo.FmcControlVO;
import org.example.springboot.vo.FmcStatusVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Service
@AllArgsConstructor
public class FmcControlServiceImpl extends BaseServiceImpl<FmcControlDao, FmcControl> implements FmcControlService {

    private static final Long THROTTLE_INTERVAL_MS = 10000L;

    @Autowired
    private RefreshConfig refreshConfig;

    @Resource
    private final MqttClientManager mqttClientManager;

    @Resource
    private final FmcMetricsService fmcMetricsService;

    @Resource
    private final FmcStatusService fmcStatusService;

    @Resource
    private final IrrigationUnitService irrigationUnitService;

    @Resource
    private final RationService rationService;

    @Resource
    private final ETService etService;

    @Resource
    private final CycleService cycleService;

    @Resource
    private final MoistureControlService moistureControlService;

    @Resource
    private SseEmitterServer sseEmitterServer;

    @Resource
    private PendingTasksService pendingTasksService;

    @Resource
    private RationPendingTasksService  rationPendingTasksService;

    @Resource
    private IrrigationStatService irrigationStatService;





    @Override
    public Result<String> sendMessageToMqtt(FmcControl fmcControl) {
        try {
            String message = JSONObject.toJSONString(fmcControl.getMessage());
            MqttMessage mqttMessage = new MqttMessage(message.getBytes());
            //启动/停止灌溉消息发送
            mqttClientManager.getMqttClientById("smart_irrigation_service").publish(fmcControl.getTopic(), mqttMessage);
            log.info("MQTT消息：{}", message);
            fmcControl.setStatus("SUCCESS");
            fmcControl.setOperationTime(new Date());
        } catch (Exception e) {
            log.error("发送MQTT消息失败！主题: {}, 消息内容: {}", fmcControl.getTopic(), fmcControl.getMessage(), e);
            fmcControl.setExMsg(e.getMessage());
            return Result.error();
        } finally {
            this.save(fmcControl);
        }
        return Result.ok();
    }



    @Override
    public void upStatusData(String message) {
        CompletableFuture.runAsync(() -> {
            // 异步解析消息
            FmcStatusVO fmcStatus = JSON.parseObject(message, FmcStatusVO.class);
            String did = fmcStatus.getDevice();
            log.info("设备编码:{}", did);
            log.info("设备消息:{}", fmcStatus);
            String status = String.valueOf(fmcStatus.getC01());
            Float c03 = fmcStatus.getC03();

            // 使用悲观锁确保线程安全
            synchronized (this) {
                // 阀门开启时,插入指标数据
                FmcMetrics fmcMetrics = fmcMetricsService.getOne(new QueryWrapper<FmcMetrics>().eq("did", did));
                if (null == fmcMetrics) {
                    log.info("步入");
                    fmcMetrics = new FmcMetrics();
                    fmcMetrics.setDid(did);
                    fmcMetrics.setEt(0f);
                    fmcMetrics.setIrrigationAmount(0f);
                    fmcMetrics.setInitialValue(c03); //水表初次累计流量值
                    fmcMetrics.setFlowRem(0f); // 剩余流量
                    fmcMetrics.setSoilMoisture(0f);
                    fmcMetricsService.save(fmcMetrics);
                }

                FmcStatus fmcStatus1 = fmcStatusService.getOne(new QueryWrapper<FmcStatus>().eq("did", did));
                if (null == fmcStatus1) {
                    fmcStatus1 = new FmcStatus();
                    BeanUtils.copyProperties(fmcStatus, fmcStatus1);
                    log.info("设备状态数据:{}", fmcStatus1);
                    fmcStatus1.setId(0);
                    fmcStatus1.setPid(fmcStatus.getProject());
                    fmcStatus1.setDid(fmcStatus.getDevice());
                    fmcStatus1.setCtime(new Date());
                    fmcStatusService.save(fmcStatus1);
                } else {
                    // 查询和更新数据库，使用乐观锁来确保不会并发更新
                    fmcStatusService.update(new UpdateWrapper<FmcStatus>()
                            .set("stime", fmcStatus.getTime())
                            .set("c01", fmcStatus.getC01())
                            .set("c02", fmcStatus.getC02())
                            .set("c03", fmcStatus.getC03())
                            .eq("did", did)
                    );
                }

                Float C01 = fmcStatus1.getC01();

                // 获取 IrrigationUnit
                IrrigationUnit irrigationUnit = irrigationUnitService.getOne(new QueryWrapper<IrrigationUnit>().eq("control_device", fmcStatus.getDevice()));
                irrigationUnit.setStatus(status);

                // 使用乐观锁确保更新是安全的
                irrigationUnitService.update(new UpdateWrapper<IrrigationUnit>()
                        .set("status", status)
                        .eq("uuid", irrigationUnit.getUuid())
                );

                Float irrigationVolume = 0f;
                Float initialValue = fmcMetrics.getInitialValue() == null ? 0f : fmcMetrics.getInitialValue();
                String type = irrigationUnit.getType();
                String uuid = irrigationUnit.getUuid();
                if (type.equals("01")) {
                    Ration ration = rationService.getOne(new QueryWrapper<Ration>().eq("irrigation_unit_uuid", uuid));
                    irrigationVolume = ration.getIrrigationVolume() == null ? 0f : ration.getIrrigationVolume();
                }
                if (type.equals("02")) {
                    Cycle cycle = cycleService.getOne(new QueryWrapper<Cycle>().eq("irrigation_unit_uuid", uuid));
                    irrigationVolume = cycle.getIrrigationVolume() == null ? 0f : cycle.getIrrigationVolume();
                }
                if (type.equals("03")) {
                    MoistureControl moistureControl = moistureControlService.getOne(new QueryWrapper<MoistureControl>().eq("irrigation_unit_uuid", uuid));
                    irrigationVolume = moistureControl.getIrrigationVolume() == null ? 0f : moistureControl.getIrrigationVolume();
                }
                if (type.equals("04")) {
                    ET et = etService.getOne(new QueryWrapper<ET>().eq("irrigation_unit_uuid", uuid));
                    irrigationVolume = et.getIrrigationVolume() == null ? 0f : et.getIrrigationVolume();
                }

                // 处理 FmcMetrics 逻辑
                log.info("did:{},C01:{}", did, C01);
                if ("1.0".equals(status)) {
                    if (C01 == 0f) {
                        fmcMetrics.setEt(0f);
                        //保存灌溉启动时间
                        IrrigationStat irrigationStat = new IrrigationStat();
                        irrigationStat.setStartTime(new Date());
                        irrigationStat.setUnitCode(irrigationUnit.getUnitCode());
                        irrigationStat.setType(type);
                        irrigationStatService.save(irrigationStat);
                    }
                    fmcMetrics.setFlowRem(irrigationVolume - c03);
                    fmcMetricsService.updateById(fmcMetrics);
                } else {
                    fmcMetrics.setIrrigationAmount(irrigationVolume);
                    fmcMetrics.setFlowRem(0f);
                    fmcMetricsService.updateById(fmcMetrics);
                    //查询待执行任务表执行顺序正序第一个,暂不包括定量灌溉
                    if(C01 == 1f){
                        irrigationStatService.update(new UpdateWrapper<IrrigationStat>()
                                .set("end_time", new Date())
                                .set("water_consumption", irrigationVolume)
                                .set("cumulative_irrigation_amount",irrigationVolume)
                                .eq("unit_code",irrigationUnit.getUnitCode())
                                .isNull("end_time"));

                        if(!type.equals("01")){
                            PendingTasks pendingTasks = pendingTasksService.getOne(new QueryWrapper<PendingTasks>().orderByAsc("sort").last("limit 1"));
                            if (pendingTasks != null) {
                                String mqttContent = pendingTasks.getMqttContent();
                                FmcControl fmcControl = JSON.parseObject(mqttContent, FmcControl.class);
                                log.info("执行下个编号的灌溉:{}", mqttContent);
                                this.sendMessageToMqtt(fmcControl);
                                pendingTasksService.removeById(pendingTasks);
                            }
                        }else{
                            RationPendingTasks rationPendingTasks = rationPendingTasksService.getOne(new QueryWrapper<RationPendingTasks>().orderByAsc("sort").last("limit 1"));
                            if (rationPendingTasks != null) {
                                String mqttContent = rationPendingTasks.getMqttContent();
                                FmcControl fmcControl = JSON.parseObject(mqttContent, FmcControl.class);
                                log.info("执行下个编号的定量灌溉:{}", mqttContent);
                                this.sendMessageToMqtt(fmcControl);
                                rationPendingTasksService.removeById(rationPendingTasks);
                            }
                        }
                    }
                }

                long currentTime = System.currentTimeMillis();

                if (currentTime - refreshConfig.getLastRefreshTime() >= THROTTLE_INTERVAL_MS) {
                    sseEmitterServer.broadcast("Refresh");
                    refreshConfig.setLastRefreshTime(currentTime);  // 更新最后更新时间
                }
            }
        });
    }






    @Override
    public PageResult<FmcControlVO> page(FmcControlQuery query) {
        QueryWrapper<FmcControl> fmcControlQueryWrapper = new QueryWrapper<>();
        if(StringUtils.isNotBlank(query.getDid())){
            fmcControlQueryWrapper.like("did", query.getDid());
        }
        fmcControlQueryWrapper.orderByDesc("create_date");
        IPage<FmcControl> page = this.page(query, fmcControlQueryWrapper);
        return new PageResult<>(FmcControlConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
    }
}